/*

* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Smart-Shop开源商城系统/ Java商城-首选电商平台系统 请务必保留此注释头信息
* |     开源地址: https://gitee.com/ningbo-qishan/gruul-mall
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     可正常分享和学习源码,未经授权 不可商用！
* |     商业版中台购买/开源版商业授权 联系技术客服
* |     官网:  https://www.73app.cn/
* ------------------------------------------------------------------------
* ------------------------------------------------------------------------
* |     Copyright (c) 2016-2999 宁波启山智软科技有限公司
* |     版权所有 ,侵权必究！
* ------------------------------------------------------------------------

*/
package com.medusa.gruul.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medusa.gruul.account.api.entity.*;
import com.medusa.gruul.account.api.model.*;
import com.medusa.gruul.account.mapper.*;
import com.medusa.gruul.account.model.dto.MemberListDto;
import com.medusa.gruul.account.model.dto.SetMemberDto;
import com.medusa.gruul.account.model.dto.UpdateMemberExpireTimeDto;
import com.medusa.gruul.account.model.dto.UpgradeMemberRankDto;
import com.medusa.gruul.account.model.vo.*;
import com.medusa.gruul.account.service.*;
import com.medusa.gruul.common.core.constant.CommonConstants;
import com.medusa.gruul.common.core.exception.ServiceException;
import com.medusa.gruul.common.core.util.*;
import com.medusa.gruul.common.data.tenant.ShopContextHolder;
import com.medusa.gruul.common.data.tenant.TenantContextHolder;
import com.medusa.gruul.common.dto.CurMiniUserInfoDto;
import com.medusa.gruul.goods.api.entity.RebateSet;
import com.medusa.gruul.goods.api.feign.RemoteGoodsService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @Description: 会员信息实现类
 * @Author: zhaokw29701
 * @Date: 2020/5/1 22:31
 **/
@Service
@Slf4j
public class MemberInfoServiceImpl extends ServiceImpl<MemberInfoMapper, MemberInfo> implements IMemberInfoService {

    @Autowired
    private IMiniAccountTagService miniAccountTagService;
    @Autowired
    private IMiniAccountTagGroupService miniAccountTagGroupService;
    @Autowired
    private MemberInfoMapper memberInfoMapper;
    @Autowired
    private MemberCardInfoMapper memberCardInfoMapper;
    @Autowired
    private IMemberCardInfoService memberCardInfoService;
    @Autowired
    private MemberCardPrivilegeMapper memberCardPrivilegeMapper;

    @Autowired
    private MemberCardPrivilegeGroupMapper memberCardPrivilegeGroupMapper;

    @Autowired
    private MiniAccountMapper miniAccountMapper;

    @Autowired
    private IMiniAccountExtendsService miniAccountExtendsService;

    @Autowired
    private IMemberSwitchService memberSwitchService;

    @Autowired
    private RemoteGoodsService remoteGoodsService;

    @Override
    public PageUtils<List<MemberListVo>> memberList(String nikeName, String becomeMemberStartTime, String becomeMemberEndTime, Long tagId, String orderSuccessStartTime, String orderSuccessEndTime, String rankCode, Long memberCardId, String memberNumber, Integer page, Integer size, Integer sortType) {
        Map<String, Object> paramMap = new HashMap<>(11);
        if (StrUtil.isNotEmpty(becomeMemberStartTime)) {
            paramMap.put("becomeMemberStartTime", becomeMemberStartTime);
        }
        if (StrUtil.isNotEmpty(becomeMemberEndTime)) {
            paramMap.put("becomeMemberEndTime", becomeMemberEndTime);
        }
        if (tagId != null) {
            paramMap.put("tagId", tagId);
        }
        if (StrUtil.isNotEmpty(orderSuccessStartTime)) {
            paramMap.put("orderSuccessStartTime", orderSuccessStartTime);
        }
        if (StrUtil.isNotEmpty(orderSuccessEndTime)) {
            paramMap.put("orderSuccessEndTime", orderSuccessEndTime);
        }
        if (memberCardId != null) {
            paramMap.put("memberCardId", memberCardId);
        }
        if (StrUtil.isNotEmpty(memberNumber)) {
            paramMap.put("memberNumber", memberNumber);
        }
        if (StrUtil.isNotBlank(nikeName)) {
            paramMap.put("nikeName", nikeName);
        }
        if (sortType != null) {
            paramMap.put("sortType", sortType);
        }
        if (StrUtil.isNotEmpty(rankCode)) {
            paramMap.put("rankCode", rankCode);
        }
        String shopId = ShopContextHolder.getShopId();
        if (StrUtil.isEmpty(shopId)) {
            throw new ServiceException("店铺id不存在");
        }
        paramMap.put("shopId", shopId);
        IPage<MemberListDto> iPage = this.baseMapper.selectByMemberList(new Page<MemberListDto>(page, size), paramMap);
        List<MemberListDto> records = iPage.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return new PageUtils(new ArrayList(0), (int) iPage.getTotal(), (int) iPage.getSize(), (int) iPage.getCurrent());
        }
        List<String> memberIdList = records.stream().map(MemberListDto::getShopUserId).collect(Collectors.toList());
        //查询会员用户标签
        Map<String, List<UserTagVo>> userTag = MapUtil.newHashMap(memberIdList.size());
        List<MiniAccountTagGroup> tagGroups = miniAccountTagGroupService.getByUserListId(memberIdList);
        if (CollectionUtil.isNotEmpty(tagGroups)) {
            List<Long> tagIdList = tagGroups.stream().map(MiniAccountTagGroup::getTagId).distinct().collect(Collectors.toList());
            List<MiniAccountTag> miniAccountTags = miniAccountTagService.getByIdList(tagIdList);
            Map<Long, MiniAccountTag> tagMap = miniAccountTags.stream().collect(Collectors.toMap(MiniAccountTag::getId, v -> v));
            tagGroups.stream().collect(Collectors.groupingBy(MiniAccountTagGroup::getUserId)).forEach((k, v) -> {
                List<UserTagVo> userTagVos = new ArrayList<>(v.size());
                for (MiniAccountTagGroup miniAccountTagGroup : v) {
                    MiniAccountTag miniAccountTag = tagMap.get(miniAccountTagGroup.getTagId());
                    if (miniAccountTag != null) {
                        UserTagVo userTagVo = new UserTagVo();
                        userTagVo.setTagId(miniAccountTag.getId());
                        userTagVo.setTagName(miniAccountTag.getTagName());
                        userTagVos.add(userTagVo);
                    }
                }
                userTag.put(k, userTagVos);
            });
        }
        //封装会员列表数据
        List<MemberListVo> vos = getMemberListVos(sortType, shopId, records, userTag);

        return new PageUtils(vos, (int) iPage.getTotal(), (int) iPage.getSize(), (int) iPage.getCurrent());
    }

    /**
     * 封装会员列表数据
     *
     * @param sortType 排序值
     * @param shopId   店铺id
     * @param records  会员记录
     * @param userTag  用户标签
     * @return com.medusa.gruul.account.model.vo.MemberListVo
     */
    private List<MemberListVo> getMemberListVos(Integer sortType, String shopId, List<MemberListDto> records, Map<String, List<UserTagVo>> userTag) {
        List<MemberListVo> vos = new ArrayList<>(records.size());
        String tenantId = TenantContextHolder.getTenantId();
        for (MemberListDto record : records) {
            MemberListVo vo = new MemberListVo();
            BeanUtils.copyProperties(record, vo);
            //获取返利设置里会员返利金额是否可用,可用：返利+用户余额  不可用：用户余额
            RebateSet rebateSet = remoteGoodsService.getRebateSet(tenantId, shopId);
            List<MemberInfo> memberInfoList = memberInfoMapper.selectList(new QueryWrapper<MemberInfo>().eq("state", 1).eq("tenant_id", tenantId).eq("user_id", record.getShopUserId()));
            //是会员
            if (memberInfoList != null && memberInfoList.size() > 0) {
                if (rebateSet != null && rebateSet.getBalanceUseCondition() != null && rebateSet.getBalanceUseCondition().contains(CommonConstants.NUMBER_ONE.toString())) {
                    vo.setSupplyBonus(record.getSupplyBonus().add(record.getRebateBonus()));
                } else {
                    vo.setSupplyBonus(record.getSupplyBonus());
                }
            } else {
                //不是会员,是普通用户
                if (rebateSet != null && rebateSet.getBalanceUseCondition() != null && rebateSet.getBalanceUseCondition().contains(CommonConstants.NUMBER_ZERO.toString())) {
                    vo.setSupplyBonus(record.getSupplyBonus().add(record.getRebateBonus()));
                } else {
                    vo.setSupplyBonus(record.getSupplyBonus());
                }
            }
            vo.setUserId(record.getShopUserId());
            List<UserTagVo> userTagVos = userTag.get(record.getShopUserId());
            vo.setUserTagVos(userTagVos);
            List<MemberInfo> memberInfos = memberInfoMapper
                    .getMemberInfoByUserId(tenantId,
                            record.getShopUserId());
            List<MemberInnerListVo> memberInnerListVos = new ArrayList<>();
            vo.setMemberRegisterTime(memberInfos.get(0).getMemberRegisterTime());
            for (MemberInfo memberInfo : memberInfos) {
                MemberInnerListVo memberInnerListVo = new MemberInnerListVo();
                MemberCardInfo memberCardInfo = memberCardInfoMapper.getApiMemberCardInfo(memberInfo.getMemberCardInfoId());
                //计算用户成为会员天数
                long becomeMemberDayNumber = 0L;
                if (memberInfo.getMemberRegisterTime() != null) {
                    becomeMemberDayNumber = DateUtil.between(LocalDateTimeUtils.convertLDTToDate(memberInfo.getMemberRegisterTime()), DateUtil.date(), DateUnit.DAY);
                }
                memberInnerListVo.setTitle(memberCardInfo.getTitle())
                        .setOpenType(memberCardInfo.getOpenType())
                        .setRankName(memberCardInfo.getRankName())
                        .setRankCode(memberCardInfo.getRankCode())
                        .setMemberRegisterTime(memberInfo.getMemberRegisterTime())
                        .setMemberNumber(memberInfo.getMemberNumber())
                        .setMemberExpireTime(memberInfo.getMemberExpireTime())
                        .setBecomeMemberDayNumber(becomeMemberDayNumber)
                        .setId(memberInfo.getId())
                        .setRegisterData(memberInfo.getRegisterData());
                memberInnerListVos.add(memberInnerListVo);
            }

            vo.setMemberInnerListVos(memberInnerListVos);
            vos.add(vo);
        }
        //按照成为会员时间降序
        if (sortType != null && sortType.equals(CommonConstants.NUMBER_THREE)) {
            vos = vos.stream().sorted(Comparator.comparing(MemberListVo::getMemberRegisterTime).reversed()).collect(Collectors.toList());
        }
        //按照成为会员时间升序
        if (sortType != null && sortType.equals(CommonConstants.NUMBER_FOUR)) {
            vos = vos.stream().sorted(Comparator.comparing(MemberListVo::getMemberRegisterTime)).collect(Collectors.toList());
        }
        return vos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setMember(SetMemberDto setMemberDto) {
        String tenantId = TenantContextHolder.getTenantId();
        setMemberDto.setTenantId(tenantId);
        //获取会员开卡方式
        MemberCardBaseInfo memberBaseInfo = memberCardInfoService.getByMemberBaseInfo(tenantId);
        Integer currentOpenType = memberBaseInfo.getCurrentOpenType();
        MemberCardInfo memberCardInfo = memberCardInfoMapper.selectMemCardInfo(setMemberDto,currentOpenType);
        String userId = setMemberDto.getUserId();
        //取时间
        Date memberRegisterTime = new Date();
        Calendar calendar = Calendar.getInstance();
        //需要将date数据转移到Calender对象中操作
        calendar.setTime(memberRegisterTime);
        //把日期往后增加n天.正数往后推,负数往前移动
        calendar.add(Calendar.DATE, memberCardInfo.getUseInDate().intValue());
        //这个时间就是日期往后推或往前移n天的结果
        Date memberExpireTime = calendar.getTime();
        MemberInfo memberInfo = new MemberInfo();
        memberInfo.setMemberCardInfoId(memberCardInfo.getId())
                .setMemberExpireTime(memberExpireTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime())
                .setMemberNumber(generateRandomNo(tenantId, 7))
                .setMemberRegisterTime(memberRegisterTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime())
                .setMemberRegisterType(2)
                .setMemberQrcode(memberCardInfo.getBackGroundPicUrl())
                .setState(1)
                .setUserId(userId);
        List<MemberInfo> memberInfos = memberInfoMapper.selectList(new QueryWrapper<MemberInfo>().eq("member_card_info_id", memberInfo.getMemberCardInfoId()).eq("user_id", memberInfo.getUserId()).eq("tenant_id", tenantId));
        if (CollectionUtil.isNotEmpty(memberInfos)) {
            throw new ServiceException("后台生成会员信息失败，已开通该类型会员请勿重复开通！", SystemCode.DATA_ADD_FAILED.getCode());
        } else {
            int insert = memberInfoMapper.insert(memberInfo);
            if (insert < 1) {
                throw new ServiceException("后台生成会员信息失败", SystemCode.DATA_ADD_FAILED.getCode());
            }
        }
    }

    @Override
    public List<MemberCardRankListVo> getMemberCardRank() {
        String tenantId = TenantContextHolder.getTenantId();
        List<MemberCardInfo> memberCardInfoList = memberCardInfoMapper.getMemberCardRank(tenantId);
        List<MemberCardRankListVo> memberCardRankListVos = new ArrayList<>();
        for (MemberCardInfo memberCardInfo : memberCardInfoList) {
            MemberCardRankListVo memberCardRankListVo = new MemberCardRankListVo();
            BeanUtils.copyProperties(memberCardInfo, memberCardRankListVo);
            //获取租户下特权开关为开启状态下的会员卡权益列表
            List<MemberPrivilegeVo> memberPrivilegeVos = memberCardPrivilegeMapper.selectMemberCardPrivilege(tenantId);
            for (MemberPrivilegeVo memberPrivilegeVo : memberPrivilegeVos) {
                MemberCardPrivilegeGroup memberCardPrivilegeGroup = memberCardPrivilegeGroupMapper.selectMemberCardPrivilegeGroup(tenantId, memberCardInfo.getId(), memberPrivilegeVo.getId());
                if (memberCardPrivilegeGroup != null) {
                    memberPrivilegeVo.setIsSelected(1);
                    memberPrivilegeVo.setValue(memberCardPrivilegeGroup.getValue());
                } else {
                    memberPrivilegeVo.setIsSelected(0);
                }
            }
            memberCardRankListVo.setMemberPrivilegeVos(memberPrivilegeVos);
            memberCardRankListVos.add(memberCardRankListVo);
        }
        return memberCardRankListVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMemberExpireTime(UpdateMemberExpireTimeDto updateMemberExpireTimeDto) {
        DateTime t1 = DateUtil.parseDateTime(updateMemberExpireTimeDto.getMemberExpireTime());
        DateTime t2 = DateTime.now();
        if (t1.compareTo(t2) < 0) {
            throw new ServiceException("pc端会员续费失败，会员卡已到期", SystemCode.DATA_UPDATE_FAILED.getCode());
        }
        //取时间
        Date date = DateUtil.parseDateTime(updateMemberExpireTimeDto.getMemberExpireTime());
        Calendar calendar = Calendar.getInstance();
        //需要将date数据转移到Calender对象中操作
        calendar.setTime(date);
        //把日期往后增加n天.正数往后推,负数往前移动
        calendar.add(Calendar.DATE, updateMemberExpireTimeDto.getDate().intValue());
        //这个时间就是日期往后推n天的结果
        date = calendar.getTime();
        updateMemberExpireTimeDto.setMemberExpireTime(DateUtil.formatDateTime(date));
        int update = memberInfoMapper.updateMemberExpireTime(updateMemberExpireTimeDto);
        if (update < 1) {
            throw new ServiceException("后台会员续费失败", SystemCode.DATA_UPDATE_FAILED.getCode());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upgradeMemberRank(UpgradeMemberRankDto upgradeMemberRankDto) {
        String tenantId = TenantContextHolder.getTenantId();
        upgradeMemberRankDto.setTenantId(tenantId);
        int update = memberInfoMapper.upgradeMemberRank(upgradeMemberRankDto);
        if (update < 1) {
            throw new ServiceException("后台会员升级失败", SystemCode.DATA_UPDATE_FAILED.getCode());
        }
    }

    @Override
    public MemberCardInfoCenterDto getMemberInfo(String tenantId, String shopUserId) {
        List<MemberCardInfoCenterDto> memberCardInfoCenterDtos = new ArrayList<>();
        MemberSwitch memberSwitch = memberSwitchService.getByTenantIdAndMemberModelMemberSwitch(tenantId, CommonConstants.NUMBER_ZERO);
        // 该处提供判断 如果后台会员功能以关闭 并不影响已购会员
        if (memberSwitch == null) {
            return null;
        }
        List<MemberInfo> memberInfos = memberInfoMapper.getMemberInfoByUserId(tenantId, shopUserId);
        for (MemberInfo memberInfo : memberInfos) {
            //忽略未注册以及会员到期的会员卡
            if (memberInfo.getState().equals(CommonConstants.NUMBER_ZERO) || memberInfo.getState().equals(CommonConstants.NUMBER_TWO)) {
                continue;
            }
            MemberCardInfoCenterDto memberCardInfoCenterDto = new MemberCardInfoCenterDto();
            memberCardInfoCenterDto.setId(memberInfo.getId())
                    .setMemberNumber(memberInfo.getMemberNumber())
                    .setState(memberInfo.getState())
                    .setMemberCardInfoId(memberInfo.getMemberCardInfoId())
                    .setMemberRegisterTime(memberInfo.getMemberRegisterTime())
                    .setMemberExpireTime(memberInfo.getMemberExpireTime());
            MemberCardInfo memberCardInfo = memberCardInfoMapper.getApiMemberCardInfo(memberInfo.getMemberCardInfoId());
            memberCardInfoCenterDto.setTitle(memberCardInfo.getTitle())
                    .setRankCode(memberCardInfo.getRankCode())
                    .setRankName(memberCardInfo.getRankName())
                    .setOpenType(memberCardInfo.getOpenType())
                    .setOpenValue(memberCardInfo.getOpenValue())
                    .setUseInDate(memberCardInfo.getUseInDate());
            //获取租户下特权开关为开启状态下的会员卡权益列表
            List<MemberCardPrivilegeGroup> memberCardPrivilegeGroups = memberCardPrivilegeGroupMapper.getByMemberCardId(tenantId, memberCardInfo.getId());
            List<MemberCardPrivilege> memberCardPrivileges = new ArrayList<>();
            for (MemberCardPrivilegeGroup memberCardPrivilegeGroup : memberCardPrivilegeGroups) {
                MemberCardPrivilege memberCardPrivilege = memberCardPrivilegeMapper.selectById(memberCardPrivilegeGroup.getPrivilegeId());
                //仅返回打开中的权益
                if (memberCardPrivilege.getOpen().equals(CommonConstants.NUMBER_ONE)) {
                    memberCardPrivilege.setDefValue(memberCardPrivilegeGroup.getValue() == null ? new BigDecimal(0) : memberCardPrivilegeGroup.getValue());
                    memberCardPrivileges.add(memberCardPrivilege);
                }
            }
            memberCardInfoCenterDto.setMemberCardPrivileges(memberCardPrivileges);
            //获取用户余额
            MiniAccountExtends accountExtends = miniAccountExtendsService.findByShopUserId(shopUserId);
            //获取返利设置里会员返利金额是否可用,可用：返利+用户余额  不可用：用户余额
            RebateSet rebateSet = remoteGoodsService.getRebateSet(tenantId, accountExtends.getShopId());
            List<MemberInfo> memberInfoList = memberInfoMapper.selectList(new QueryWrapper<MemberInfo>()
                    .eq("state", 1)
                    .eq("tenant_id", tenantId)
                    .eq("user_id", shopUserId));
            //是会员
            if (CollectionUtil.isNotEmpty(memberInfoList)) {
                if (rebateSet != null && rebateSet.getBalanceUseCondition() != null && rebateSet.getBalanceUseCondition().contains(CommonConstants.NUMBER_ONE.toString())) {
                    memberCardInfoCenterDto.setSupplyBonus(accountExtends.getSupplyBonus().add(accountExtends.getRebateBonus()));
                } else {
                    memberCardInfoCenterDto.setSupplyBonus(accountExtends.getSupplyBonus());
                }
            } else {//不是会员,是普通用户
                if (rebateSet != null && rebateSet.getBalanceUseCondition() != null && rebateSet.getBalanceUseCondition().contains(CommonConstants.NUMBER_ZERO.toString())) {
                    memberCardInfoCenterDto.setSupplyBonus(accountExtends.getSupplyBonus().add(accountExtends.getRebateBonus()));
                } else {
                    memberCardInfoCenterDto.setSupplyBonus(accountExtends.getSupplyBonus());
                }
            }
            memberCardInfoCenterDtos.add(memberCardInfoCenterDto);
        }
        Optional<MemberCardInfoCenterDto> first = memberCardInfoCenterDtos
                .stream().max(Comparator.comparing(MemberCardInfoCenterDto::getRankCode));
        return first.orElse(null);
    }

    @Override
    public MemberTopCardInfoDto getTopMemberCardInfo(String tenantId) {
        List<MemberCardInfo> memberCardInfoList = memberCardInfoMapper.getMemberCardInfoByTenantId(tenantId);
        memberCardInfoList = memberCardInfoList.stream()
                //过滤出已开启的权益
                .filter(item -> item.getIsOpen().equals(CommonConstants.NUMBER_ONE))
                .sorted(Comparator.comparing(MemberCardInfo::getRankCode).reversed())
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(memberCardInfoList)) {
            return null;
        }
        MemberTopCardInfoDto memberTopCardInfoDto = new MemberTopCardInfoDto();
        memberTopCardInfoDto.setBackGroundPicUrl(memberCardInfoList.get(0).getBackGroundPicUrl())
                .setBuyGoods(memberCardInfoList.get(0).getBuyGoods())
                .setConsumeCondition(memberCardInfoList.get(0).getConsumeCondition())
                .setId(memberCardInfoList.get(0).getId())
                .setIntroduce(memberCardInfoList.get(0).getIntroduce())
                .setIsOpen(memberCardInfoList.get(0).getIsOpen())
                .setOpenType(memberCardInfoList.get(0).getOpenType())
                .setOpenValue(memberCardInfoList.get(0).getOpenValue())
                .setRankCode(memberCardInfoList.get(0).getRankCode())
                .setRankName(memberCardInfoList.get(0).getRankName())
                .setStyle(memberCardInfoList.get(0).getStyle())
                .setTitle(memberCardInfoList.get(0).getTitle())
                .setUseInDate(memberCardInfoList.get(0).getUseInDate());

        //获取租户下特权开关为开启状态下的会员卡权益列表
        List<MemberPrivilegeVo> memberPrivilegeVos = memberCardPrivilegeMapper.selectMemberCardPrivilege(tenantId);
        for (MemberPrivilegeVo memberPrivilegeVo : memberPrivilegeVos) {
            MemberCardPrivilegeGroup memberCardPrivilegeGroup = memberCardPrivilegeGroupMapper.selectMemberCardPrivilegeGroup(tenantId, memberCardInfoList.get(0).getId(), memberPrivilegeVo.getId());
            if (memberCardPrivilegeGroup != null) {
                memberPrivilegeVo.setIsSelected(1);
                memberPrivilegeVo.setValue(memberCardPrivilegeGroup.getValue());
            } else {
                memberPrivilegeVo.setIsSelected(0);
            }
        }
        List<MemberPrivilegeDto> memberPrivilegeDtos = new ArrayList<>();
        for (MemberPrivilegeVo memberPrivilegeVo : memberPrivilegeVos) {
            MemberPrivilegeDto memberPrivilegeDto = new MemberPrivilegeDto();
            BeanUtils.copyProperties(memberPrivilegeVo, memberPrivilegeDto);
            memberPrivilegeDto.setDefValue(memberPrivilegeVo.getValue());
            memberPrivilegeDtos.add(memberPrivilegeDto);
        }

        memberTopCardInfoDto.setMemberCardPrivileges(memberPrivilegeDtos);
        return memberTopCardInfoDto;

    }

    @Override
    public MemberCardUpgradeVo getMemberCardUpgrade(String memberId) {
        MemberCardUpgradeVo memberCardUpgradeVo = new MemberCardUpgradeVo();
        String tenantId = TenantContextHolder.getTenantId();
        MemberInfo memberInfo = memberInfoMapper.selectById(memberId);
        String userId = "";
        if (memberInfo != null && memberInfo.getUserId() != null) {
            String shopUserId = memberInfo.getUserId();
            userId = miniAccountMapper.getUserInfoByShopUserId(tenantId, shopUserId);
            if (userId != null) {
                MiniAccount miniAccount = miniAccountMapper.getMemberInfo(tenantId, userId);
                MiniAccountExtends accountExtends = miniAccountExtendsService.findByShopUserId(shopUserId);
                //获取返利设置里会员返利金额是否可用,可用：返利+用户余额  不可用：用户余额
                String shopId = ShopContextHolder.getShopId();
                RebateSet rebateSet = remoteGoodsService.getRebateSet(tenantId, shopId);
                List<MemberInfo> memberInfoList = memberInfoMapper.selectList(new QueryWrapper<MemberInfo>().eq("state", 1).eq("tenant_id", tenantId).eq("user_id", shopUserId));
                //是会员
                if (memberInfoList != null && memberInfoList.size() > 0) {
                    if (rebateSet != null && rebateSet.getBalanceUseCondition() != null && rebateSet.getBalanceUseCondition().contains(CommonConstants.NUMBER_ONE.toString())) {
                        memberCardUpgradeVo.setAccountBalance(accountExtends.getSupplyBonus().add(accountExtends.getRebateBonus()));
                    } else {
                        memberCardUpgradeVo.setAccountBalance(accountExtends.getSupplyBonus());
                    }
                } else {
                    //不是会员,是普通用户
                    if (rebateSet != null && rebateSet.getBalanceUseCondition() != null && rebateSet.getBalanceUseCondition().contains(CommonConstants.NUMBER_ZERO.toString())) {
                        memberCardUpgradeVo.setAccountBalance(accountExtends.getSupplyBonus().add(accountExtends.getRebateBonus()));
                    } else {
                        memberCardUpgradeVo.setAccountBalance(accountExtends.getSupplyBonus());
                    }
                }

                memberCardUpgradeVo.setAvatarUrl(miniAccount.getAvatarUrl())
                        .setNikeName(miniAccount.getNikeName())
                        .setUserId(userId);
                BigDecimal integral = miniAccountMapper.getIntegralByShopUserId(tenantId, memberInfo.getUserId());
                //账户可用积分
                memberCardUpgradeVo.setUseAmount(integral);
                MemberInfo memberInfoTemp = memberInfoMapper.selectById(memberId);
                MemberCardInfo memberCardInfoTemp = memberCardInfoMapper.getApiMemberCardInfo(memberInfoTemp.getMemberCardInfoId());
                ZoneId zoneId = ZoneId.systemDefault();
                ZonedDateTime zdt = memberInfoTemp.getMemberExpireTime().atZone(zoneId);
                Date date = Date.from(zdt.toInstant());
                Date date2 = new Date();
                int day = ApiMemberInfoServiceImpl.differentDaysByMillisecond(date2, date);
                if (day < 0) {
                    day = 0;
                }
                memberCardUpgradeVo
                        .setRemainDate(String.valueOf(day))
                        .setRankCode(memberCardInfoTemp.getRankCode())
                        .setRankName(memberCardInfoTemp.getRankName())
                        .setMemberNumber(memberInfoTemp.getMemberNumber());

                List<MemberCardInfoCenterVo> memberCardInfoCenterVos = new ArrayList<>();
                List<MemberCardInfo> memberCardInfoList = memberCardInfoService.getCurrentMemberCardInfo(tenantId);
                for (MemberCardInfo memberCardInfo : memberCardInfoList) {
                    MemberCardInfoCenterVo memberCardInfoCenterVo = getMemberCardInfoCenterVo(memberCardUpgradeVo, tenantId, memberCardInfo);
                    memberCardInfoCenterVos.add(memberCardInfoCenterVo);
                }
                memberCardUpgradeVo.setMemberCardInfoCenterVos(memberCardInfoCenterVos);
            }
        }
        return memberCardUpgradeVo;
    }

    /**
     * 封装用户卡相关信息
     *
     * @param memberCardUpgradeVo com.medusa.gruul.account.model.vo.MemberCardUpgradeVo
     * @param tenantId            租户id
     * @param memberCardInfo      会员卡相关信息
     * @return com.medusa.gruul.account.model.vo.MemberCardInfoCenterVo
     */
    private MemberCardInfoCenterVo getMemberCardInfoCenterVo(MemberCardUpgradeVo memberCardUpgradeVo, String tenantId, MemberCardInfo memberCardInfo) {
        MemberCardInfoCenterVo memberCardInfoCenterVo = new MemberCardInfoCenterVo();
        memberCardInfoCenterVo.setMemberCardInfoId(memberCardInfo.getId());
        memberCardInfoCenterVo
                .setTitle(memberCardInfo.getTitle())
                .setRankCode(memberCardInfo.getRankCode())
                .setRankName(memberCardInfo.getRankName())
                .setOpenType(memberCardInfo.getOpenType())
                .setOpenValue(memberCardInfo.getOpenValue())
                .setUseInDate(memberCardInfo.getUseInDate())
                .setBackGroundPicUrl(memberCardInfo.getBackGroundPicUrl())
                .setIsOpen(memberCardInfo.getIsOpen());
        // 实际支付金额（积分）：要升级套餐价格/有效天数*剩余时长数
        BigDecimal actualOpenValue = memberCardInfoCenterVo.getOpenValue().multiply(new BigDecimal(memberCardUpgradeVo.getRemainDate())).divide(new BigDecimal(memberCardInfoCenterVo.getUseInDate()), 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
        memberCardInfoCenterVo.setActualOpenValue(actualOpenValue);
        // 获取租户下特权开关为开启状态下的会员卡权益列表
        List<MemberPrivilegeVo> memberPrivilegeVos = memberCardPrivilegeMapper.selectMemberCardPrivilege(tenantId);
        for (MemberPrivilegeVo memberPrivilegeVo : memberPrivilegeVos) {
            MemberCardPrivilegeGroup memberCardPrivilegeGroup = memberCardPrivilegeGroupMapper.selectMemberCardPrivilegeGroup(tenantId, memberCardInfo.getId(), memberPrivilegeVo.getId());
            if (memberCardPrivilegeGroup != null) {
                memberPrivilegeVo.setIsSelected(1);
                memberPrivilegeVo.setValue(memberCardPrivilegeGroup.getValue());
            } else {
                memberPrivilegeVo.setIsSelected(0);
            }
        }

        memberCardInfoCenterVo.setMemberCardPrivileges(memberPrivilegeVos);
        return memberCardInfoCenterVo;
    }

    @Override
    public PageUtils<List<MemberInnerListVo>> getMemberRecord(Integer page, Integer size, String shopUserId, String memberNumber, String title, String rankName, String becomeMemberStartTime, String becomeMemberEndTime) {
        Map<String, Object> paramMap = new HashMap<>(7);
        if (StrUtil.isNotEmpty(becomeMemberStartTime)) {
            paramMap.put("becomeMemberStartTime", becomeMemberStartTime);
        }
        if (StrUtil.isNotEmpty(becomeMemberEndTime)) {
            paramMap.put("becomeMemberEndTime", becomeMemberEndTime);
        }
        if (StrUtil.isNotEmpty(shopUserId)) {
            paramMap.put("shopUserId", shopUserId);
        }
        if (StrUtil.isNotBlank(memberNumber)) {
            paramMap.put("memberNumber", "%" + memberNumber + "%");
        }
        if (StrUtil.isNotBlank(rankName)) {
            AtomicReference<String> name = new AtomicReference<>("%");
            rankName.chars().mapToObj(obj -> (char) obj).forEach(obj -> {
                name.set(name.get().concat(obj.toString()).concat("%"));
            });
            paramMap.put("rankName", name.toString());
        }
        if (StrUtil.isNotBlank(title)) {
            AtomicReference<String> name = new AtomicReference<>("%");
            title.chars().mapToObj(obj -> (char) obj).forEach(obj -> {
                name.set(name.get().concat(obj.toString()).concat("%"));
            });
            paramMap.put("title", name.toString());
        }
        String shopId = ShopContextHolder.getShopId();
        if (StrUtil.isEmpty(shopId)) {
            throw new ServiceException("店铺id不存在");
        }
        paramMap.put("shopId", shopId);
        IPage<MemberInnerListVo> iPage = this.baseMapper.getMemberRecord(new Page<MemberInnerListVo>(page, size), paramMap);
        List<MemberInnerListVo> records = iPage.getRecords();
        if (CollectionUtil.isEmpty(records)) {
            return new PageUtils(new ArrayList(0), (int) iPage.getTotal(), (int) iPage.getSize(), (int) iPage.getCurrent());
        }
        return new PageUtils(records, (int) iPage.getTotal(), (int) iPage.getSize(), (int) iPage.getCurrent());
    }

    @Override
    public List<UseMemberCardRankVo> getUseMemberCardRank() {
        //获取当前使用中的会员卡
        MemberCardBaseInfo memberCardBaseInfo = memberCardInfoService.getByMemberBaseInfo(TenantContextHolder.getTenantId());
        List<MemberCardInfoListResultDto> cardInfoList = memberCardInfoService.getMemberCardInfoList(new MemberCardInfoListDto().setOpenType(memberCardBaseInfo.getCurrentOpenType()).setTenantId(memberCardBaseInfo.getTenantId()));
        return cardInfoList.stream().map(obj -> BeanUtil.toBean(obj, UseMemberCardRankVo.class)).collect(Collectors.toList());
    }

    @Override
    public JumpDetailVo getJumpDetail() {
        JumpDetailVo vo = new JumpDetailVo();
        vo.setMemberOpen(CommonConstants.NUMBER_ZERO);
        vo.setWhetherMember(CommonConstants.NUMBER_ZERO);
        vo.setHistoryBuy(CommonConstants.NUMBER_ZERO);
        String tenantId = TenantContextHolder.getTenantId();
        MemberSwitch memberSwitch = memberSwitchService.getByTenantIdAndMemberModelMemberSwitch(tenantId, CommonConstants.NUMBER_ZERO);
        vo.setMemberOpen(memberSwitch.getState());
        CurMiniUserInfoDto miniReqeustAccountInfo = CurUserUtil.getMiniReqeustAccountInfo();
        List<MemberInfo> memberInfos = this.baseMapper.getMemberInfoByUserId(tenantId, miniReqeustAccountInfo.getShopUserId());
        //不存在任何会员卡当前用户肯定不是会员，也没有买过会员卡
        if (CollectionUtil.isEmpty(memberInfos)) {
            vo.setWhetherMember(CommonConstants.NUMBER_ZERO);
            vo.setHistoryBuy(CommonConstants.NUMBER_ZERO);
        } else {
            vo.setHistoryBuy(CommonConstants.NUMBER_ONE);
            //判断当前是否存在未过期的会员卡
            List<MemberInfo> exit = memberInfos.stream().filter(obj ->
                    LocalDateTimeUtils.getSecondsByTime(obj.getMemberExpireTime()) < System.currentTimeMillis()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(exit)) {
                vo.setWhetherMember(CommonConstants.NUMBER_ONE);
            }
        }
        return vo;
    }

    /**
     * 生成会员卡编号，格式：租户id+yyMMdd+7位随机数
     *
     * @param range
     * @return
     */
    @SneakyThrows
    public static String generateRandomNo(String tenantId, int range) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        String format = sdf.format(new Date());
        return tenantId + format + RandomUtil.randomNumbers(range);
    }


}
